package homework_5;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.*;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;


public class Test {

	static final String downloadUrl = "http://www.ibilibili.com/video/av";
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		DBHelper sqlDataBase = new DBHelper();
		
		Map<String, int[]> map = new HashMap<String, int[]>();
		
		map.put("动画", new int[]{24, 25, 47, 27});
		map.put("音乐", new int[]{28, 31, 30, 59, 29, 54, 130});
		map.put("舞蹈", new int[]{20, 154, 156});
		map.put("游戏", new int[]{17, 65, 19, 136, 121});
		map.put("时尚", new int[]{157, 158, 164, 159});
		map.put("科技", new int[]{37 , 124, 122, 39, 95, 98});
		map.put("生活", new int[]{138, 21, 76, 75, 161, 162, 163});
		map.put("番剧", new int[]{33, 32, 51, 152, 153});
		map.put("鬼畜", new int[]{22, 26, 126, 127});
		map.put("广告", new int[]{166});
		map.put("娱乐", new int[]{71, 137, 131});
		map.put("影视", new int[]{82, 85, 145, 146, 147, 83, 5, 34, 86, 128});
		
		
		int cateId = 1;
		for (Map.Entry<String, int[]> entry : map.entrySet()) {
			sqlDataBase.createTable(cateId);
			for (int tid : entry.getValue()) {
				System.out.println("tid:" + tid + " is begining");
				for (int page = 0; page <= 1000; page++) {
					try {
						HttpClient httpClient = HttpClients.createDefault();
						HttpGet req = new HttpGet("http://api.bilibili.com/archive_rank/getarchiverankbypartion?callback=?&type=jsonp&tid=" + tid + "&pn=" + page);
						req.addHeader("Accept", "application/json, text/javascript, */*; q=0.01");
						req.addHeader("Accept-Encoding", "gzip, deflate, sdch");
						req.addHeader("Accept-Language", "zh-CN,zh;q=0.8");
						req.addHeader("Content-Type", "text/html; charset=UTF-8");
						req.addHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36");
						HttpResponse response = httpClient.execute(req);
						HttpEntity repEntity = response.getEntity();
						String json = EntityUtils.toString(repEntity);
						LinkedList<VideoModel> models = parseJson(json, cateId, entry.getKey());
						for (VideoModel model : models) {
							sqlDataBase.insertModel(model);
						}
						models = null;
						System.out.println("page " + page + " done!");
					} catch (Exception e) {
						System.out.println("数据获取失败！");
						e.printStackTrace();
					} 
					
				}
				System.out.println("tid:" + tid + " was finished");
			}
			cateId++;
		}
		
		// download Top 3 videos in each category
		
		for (; cateId > 0; cateId--) {
			ArrayList<VideoModel> models = sqlDataBase.obtainTopModels(cateId, 3);
			for (VideoModel model : models) {
				String link = obtainDawnloadLink(model);
				downloadVideo(link, model.aid);
			}
		}
		
		sqlDataBase.close();
	}
	
	// parse json data and transform to VideoModel
	public static LinkedList<VideoModel> parseJson(String json, int cateId, String categary) {
		JSONObject jsonObject = new JSONObject(json);
		JSONObject jsonData = jsonObject.getJSONObject("data");
		JSONObject array = jsonData.getJSONObject("archives");
		int size = jsonData.getJSONObject("page").getInt("size");
		LinkedList<VideoModel> models = new LinkedList<VideoModel>();
		for (Integer i = 0; i < size; i++) {
			JSONObject object = array.getJSONObject(i.toString());
			VideoModel model = new VideoModel();
			model.cateId = cateId;
			model.aid = object.getInt("aid") + "";
			model.author = object.getString("author");
			model.category = categary;
			model.title = object.getString("title");
			model.typeName = object.getString("tname");
			model.favorite = object.getJSONObject("stat").getInt("favorite");
			model.coins = object.getJSONObject("stat").getInt("coin");
			models.add(model);
		}
		return models;
	}
	
	public static String obtainDawnloadLink(VideoModel model) {
		String link = null;
		try {
			System.out.println(model.title + "下载开始");
			Document document = Jsoup.connect(downloadUrl + model.aid).get();
			Element list = document.getElementById("firstLi");
			link = list.select("a[href]").get(2).attr("href");
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("获取下载链接失败");
			e.printStackTrace();
		}
		return link;
	}
	
	public static void downloadVideo(String link, String fileName) {
		
		try {
			URL httpurl = new URL(link);
			InputStream inputStream = new BufferedInputStream(httpurl.openStream());
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			byte[] buf = new byte[4096];
			int n = 0;
			while (-1 != (n=inputStream.read(buf))) {
				outputStream.write(buf, 0, n);
			}
			inputStream.close();
			outputStream.close();
			byte[] reponse = outputStream.toByteArray();
			FileOutputStream fileOutputStream = new FileOutputStream("/Users/jingyeli/Downloads/BiliBiliTop3/" + fileName + ".mp4");
			fileOutputStream.write(reponse);
			fileOutputStream.close();
			System.out.println(fileName + "下载完成");
		} catch (IOException e) {
			System.out.println("下载失败");
			e.printStackTrace();
		} finally {
			
		}
	}
}
